package lion.dev.image;

import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import com.gif4j.GifDecoder;
import com.gif4j.GifEncoder;
import com.gif4j.GifFrame;
import com.gif4j.GifImage;
import com.gif4j.GifTransformer;

/**
 * a gif4j component
 *
 * @author lion
 * @date 2016年9月27日
 */
public class GIF4JHandler implements IImageHandler {

	private GifImage image;

	@Override
	public void read(InputStream src) throws IOException {

		image = GifDecoder.decode(src);
	}

	@Override
	public void read(BufferedImage image) {

		this.image = new GifImage();
		this.image.addGifFrame(new GifFrame(image));
	}

	/**
	 * not support ,return a copy
	 */
	@Override
	public IImageHandler compress(float quality, String type) {

		if (this.image.getNumberOfFrames() == 1) {

			GIF4JHandler handler = new GIF4JHandler();
			GifImage gif = new GifImage();
			gif.addGifFrame(
					new GifFrame(DefaultImageHandler.compress(this.image.getFrame(0).getAsBufferedImage(), quality, type)));
			handler.image = gif;
			return handler;
		} else {
			return this.resizeScale(1);
		}
	}

	@Override
	public IImageHandler resize(int width, int height) {

		GifImage result = GifTransformer.resize(this.image, width, height, true);
		GIF4JHandler handler = new GIF4JHandler();
		handler.image = result;
		return handler;
	}

	@Override
	public IImageHandler resizeWidth(int width) {

		int height = this.image.getScreenHeight() * width / this.image.getScreenWidth();

		return this.resize(width, height);
	}

	@Override
	public IImageHandler resizeHeight(int height) {

		int width = this.image.getScreenWidth() * height / this.image.getScreenHeight();

		return this.resize(width, height);
	}

	@Override
	public IImageHandler resizeScale(float percent) {

		GifImage result = GifTransformer.scale(this.image, percent, percent, true);
		GIF4JHandler handler = new GIF4JHandler();
		handler.image = result;

		return handler;
	}

	@Override
	public IImageHandler rotate(Rotation rotation) {

		GifImage result = this.image;

		switch (rotation) {
		case CW_90:
			result = GifTransformer.rotate90Right(this.image);
			break;
		case CW_180:
			result = GifTransformer.rotate180(this.image);
			break;
		case CW_270:
			result = GifTransformer.rotate90Left(this.image);
			break;
		case FLIP_HORZ:
			result = GifTransformer.flipHorizontal(this.image);
			break;
		case FLIP_VERT:
			result = GifTransformer.flipVertical(this.image);
			break;
		}
		GIF4JHandler handler = new GIF4JHandler();
		handler.image = result;
		return handler;
	}

	@Override
	public IImageHandler crop(int x, int y, int width, int height) {

		GifImage result = GifTransformer.crop(this.image, new Rectangle(x, y, width, height));
		GIF4JHandler handler = new GIF4JHandler();
		handler.image = result;

		return null;
	}

	@Override
	public void write(OutputStream os, String type) throws IOException {

		GifEncoder.encode(this.image, os);
	}

	/**
	 * not support
	 */
	@Override
	public IImageHandler watermark(BufferedImage watermark, Directoin directoin, float opacity) {

		if (this.image.getNumberOfFrames() == 1) {

			GIF4JHandler handler = new GIF4JHandler();
			GifImage gif = new GifImage();
			gif.addGifFrame(
					new GifFrame(DefaultImageHandler.merge(this.image.getFrame(0).getAsBufferedImage(), watermark, directoin, opacity)));
			handler.image = gif;
			return handler;
		} else {
			return this.resizeScale(1);
		}

	}

	/**
	 * not support
	 */
	@Override
	public IImageHandler watermark(BufferedImage watermark, int x, int y, float opacity) {

		if (this.image.getNumberOfFrames() == 1) {

			GIF4JHandler handler = new GIF4JHandler();
			GifImage gif = new GifImage();
			gif.addGifFrame(
					new GifFrame(DefaultImageHandler.merge(this.image.getFrame(0).getAsBufferedImage(), watermark, x, y, opacity)));
			handler.image = gif;
			return handler;
		} else {
			return this.resizeScale(1);
		}
	}

	/**
	 * not support
	 */
	@Override
	public IImageHandler sharpen(int times) {

		if (this.image.getNumberOfFrames() == 1) {

			GIF4JHandler handler = new GIF4JHandler();
			GifImage gif = new GifImage();
			gif.addGifFrame(
					new GifFrame(DefaultImageHandler.sharpen(this.image.getFrame(0).getAsBufferedImage(), times)));
			handler.image = gif;
			return handler;
		} else {
			return this.resizeScale(1);
		}
	}

	@Override
	public IImageHandler limit(int maxwidth, int maxheight) {

		int width = image.getScreenWidth();
		int height = image.getScreenHeight();
		if (maxwidth > 0 && width > maxwidth) {
			height = height * (maxwidth / width);
			width = maxwidth;
		}
		if (maxheight > 0 && height > maxheight) {
			width = width * height / maxheight;
			height = maxheight;
		}
		return resize(width, height);
	}

}
